package graph;

import java.util.LinkedList;

import visitorpattern.Visitor;
import visitorpattern.VisitorElement;

import bookworm.Review;

public class BookReviewNode implements VisitorElement
{
	private Review reviewData;
	private LinkedList<BookReviewEdge> incidentEdges;
	
	public BookReviewNode(Review data)
	{
		this.reviewData = data;
		incidentEdges = new LinkedList<BookReviewEdge>();
	}
	
	public Review getReviewData()
	{
		return this.reviewData;
	}
	
	public LinkedList<BookReviewEdge> getIncidentEdges()
	{
		return this.incidentEdges;
	}
	
	public void setReviewData(Review newReviewData)
	{
		if(newReviewData != null)
		{
			this.reviewData = newReviewData;
		}
	}
	
	public void addIncidentEdge(BookReviewEdge newEdge)
	{
		this.incidentEdges.add(newEdge);
	}
	
	public void removeIncidentEdge(BookReviewEdge toRemove)
	{
		for(int i = 0; i < this.incidentEdges.size(); i++)
		{
			if(this.incidentEdges.get(i) == toRemove)
			{
				this.incidentEdges.remove(i);
				break;
			}
		}
	}
	
	public BookReviewEdge getIncidentEdge(int index)
	{
		if(index >= 0 && index < this.incidentEdges.size())
		{
			return this.incidentEdges.get(index);
		}
		else
		{
			return null;//return null edge.
		}
	}
	
	
	
	/**
	 * this method gets the nodes on the other side of the incident edges
	 * that are on "LinkedList<BookReviewEdge>" which is attribute of this class)  
	 * @return the neighbor nodes of this node
	 */
	public LinkedList<BookReviewNode> getNeighborsOfNode()
	{
		LinkedList<BookReviewNode> neighbors = new LinkedList<BookReviewNode>();
		for(int i = 0; i < this.incidentEdges.size(); i++)
		{
			BookReviewEdge incidentEdge = this.incidentEdges.get(i);
			BookReviewNode neighbor = incidentEdge.getOppositeNodeConnected(this);
			neighbors.add(neighbor);
		}
		
		return neighbors;
	}
	
	
	/**
	 * Checks if current node has one tag in common with other node
	 * @param otherNode
	 * @return
	 */
	public boolean shareOneSameTag(BookReviewNode otherNode)
	{
		LinkedList<String> tagsFromThisNode = this.getReviewData().getTags();
		LinkedList<String> tagsFromOtherNode = otherNode.getReviewData().getTags();
		for(int i = 0; i < tagsFromThisNode.size(); i++)
		{
			String tagFromThisNode = tagsFromThisNode.get(i);
			for(int j = 0; j < tagsFromOtherNode.size(); j++)
			{
				String tagFromOtherNode = tagsFromOtherNode.get(j);
				if(tagFromThisNode.compareToIgnoreCase(tagFromOtherNode) == 0)
				{
					//they share at least one same tag
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * Checks if current node has one author in common with other node
	 * @param otherNode
	 * @return
	 */
	public boolean shareOneSameAuthor(BookReviewNode otherNode)
	{
		LinkedList<String> authorsFromThisNode = this.getReviewData().getAuthors();
		LinkedList<String> authorsFromOtherNode = otherNode.getReviewData().getAuthors();
		for(int i = 0; i < authorsFromThisNode.size(); i++)
		{
			String authorFromThisNode = authorsFromThisNode.get(i);
			for(int j = 0; j < authorsFromOtherNode.size(); j++)
			{
				String authorFromOtherNode = authorsFromOtherNode.get(j);
				if(authorFromThisNode.compareTo(authorFromOtherNode) == 0)
				{
					//they share at least one same author
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void accept(Visitor visitor) 
	{
		visitor.visitBookReviewNode(this);
		
	}
	
	/**
	 * The function below checks if the current and other node are connected by an Edge
	 * @param otherNode
	 * @return
	 */
	public boolean isAlreadyConnectedTo(BookReviewNode otherNode)
	{
		LinkedList<BookReviewNode> neighbors = this.getNeighborsOfNode();
		for(int i = 0; i < neighbors.size(); i++)
		{
			BookReviewNode neighbor = neighbors.get(i);
			if(neighbor == otherNode)
			{
				return true;
			}
		}
		return false;
	}

}

